#!/bin/env bash
#
# 时间: 2023-6-9
# 版本: 0.2
# 作者: fanyongfeng
# 脚本名称：mysql 数据库每个库全量备份
# 脚本使用：配合 crontab 使用
# 00  01  *  *  6 /usr/bin/bash mysql_backup_all.sh


nowDate=`date +%Y%m%d`
beginTime=`date +"%Y年%m月%d日 %H:%M:%S"`
# 备份目录
bakDir=/data/mysql_data_backup
# 日志文件
logFile=$bakDir/logs/$nowDate-bak.log

if [[ ! -d $bakDir/logs ]];then
    mkdir -p $bakDir/logs
fi


# mysql_user_info 文件格式：用户名 密码 数据库名
USER_INFO_dir=/root/script/mysql_backup
USER_INFO=${USER_INFO_dir}/mysql_user_info

if [[ -s $USER_INFO ]];then
    mysql_user=(`awk '{print $1}' ${USER_INFO}  | uniq`)
    mysql_pass=(`awk '{print $2}' ${USER_INFO}  | uniq`)

    len=${#mysql_user[*]}

    # 获取所有用户相关信息
    for (( i = 0; i < $len; i++ ))
    do
        declare -A user_info
        user_info["${mysql_user[$i]}"]=${mysql_pass[$i]}  
    done

    # 获取所有库名

    for key in ${!user_info[@]}
    do
        old_databases=(`awk -v I=${key} 'I==$1{print $3}' ${USER_INFO}`)
        databases=(`/data/mysql/bin/mysql -u${key} -p${user_info[$key]} -e "show databases; " 2>/dev/null | sed 1d | grep -Ev "schema|mysql"`)
   
        if [[ ${#old_databases[*]} -gt ${#databases[*]} ]];then
            # 旧文件有多余数据库 
            for i in ${databases[@]}
            do
                c=$(echo ${old_databases[*]} | sed 's/\<'$i'\>//') #通过尖括号完全匹配数字，防止出现 2，23这种元素2都会被修改的情况
                unset old_databases
                old_databases=${c[@]}
            done
            
            excess=$(echo ${c[@]} | sed 's/ /\|/g')

            grep -Ev "${excess}" ${USER_INFO} >> tmp
            mv ${USER_INFO} ${USER_INFO}-${nowDate}.bak
            sort tmp > ${USER_INFO}
        elif [[ ${#old_databases[*]} -lt ${#databases[*]} ]];then
            # 旧文件与新文件相比有多余的数据库,此处没有写完需要补充
            # get the difference set 
            cp ${USER_INFO} ${USER_INFO}-${nowDate}.bak
            for i in ${old_databases[@]}
            do
                c=$(echo ${databases[*]} | sed 's/\<'$i'\>//') #通过尖括号完全匹配数字，防止出现 2，23这种元素2都会被修改的情况
                unset databases
                databases=${c[@]}
            done
            
            # input the 
            for db_name in ${databases[*]}
            do
                echo $key' '${user_info[$key]}' '$db_name  >>  ${USER_INFO}
            done
            sort ${USER_INFO} > tmp
            rm -f ${USER_INFO}
            mv tmp ${USER_INFO}
        fi

    done
    

    # 获取用户名密码数据库等信息进行数据备份
    for db_name in $(awk '/^[^#]/{print $3}' $USER_INFO); do
        USER=$(awk -v I=$db_name 'I==$3{print $1}' $USER_INFO)
        PASS=$(awk -v I=$db_name 'I==$3{print $2}' $USER_INFO)
        
        if [[ ! -d "${bakDir}/${db_name}" ]] ; then
            mkdir -p ${bakDir}/${db_name}
        fi
        # 备份文件
        gzDumpFile="${db_name}_${nowDate}.sql.tgz"
        # 全量备份（对所有数据库备份）
        /data/mysql/bin/mysqldump --set-gtid-purged=OFF -u${USER} -p${PASS} ${db_name} | gzip > ${bakDir}/${db_name}/$gzDumpFile

        endTime=`date +"%Y年%m月%d日 %H:%M:%S"`
        echo 开始:$beginTime 结束:$endTime  ${db_name} >> $logFile
        sha1sum ${bakDir}/${db_name}/${gzDumpFile} >> $logFile
        chattr +i $logFile
        find ${bakDir}/${db_name} -type f -mtime +30 -name "*.sql.tgz" -exec rm -rf {} \;
    done
    chown -R app: ${bakDir}
else
    echo "$beginTime no mysql info" >> $logFile
    exit 1
fi
